AWS Cloud9からSAM Localをためしてみる #serverless #adventcalendar #reinvent
どうも!大阪オフィスの西村祐二です。
このエントリはServerless Advent Calendar 2017の21日目の記事となります。
AWS Cloud9を利用する際に、EC2上に新しく構築するとAWS Cloud9用のAMIを使用してインスタンスが作成されます。 このAMIにはSAM Localがデフォルトでインストールされているので今回こちらをためしたいと思います。
AWS Cloud9の環境構築
下記ブログがとても参考になります。 本ブログではすでにAWS Cloud9のIDEが利用できることを前提にすすめてまいります。
AWS Cloud9のIDEで提供されるターミナルで作業していきます。
SAM Localをためしてみる
SAM Localについては下記ブログを参考にします。
確認
SAM Local が入っているか確認します。 コマンドで確認するときちんと入っているようですね。
0.2.2
が入っているようですね。
最新版があるようなのであげておきましょう。
$ npm update -g aws-sam-local > [email protected] preuninstall /home/ec2-user/.nvm/versions/node/v6.11.4/lib/node_modules/aws-sam-local > go-npm uninstall > [email protected] postinstall /home/ec2-user/.nvm/versions/node/v6.11.4/lib/node_modules/aws-sam-local > go-npm install Downloading from URL: https://github.com/awslabs/aws-sam-local/releases/download/v0.2.4/sam_0.2.4_linux_amd64.tar.gz + [email protected] updated 3 packages in 3.25s $ sam --version sam version 0.2.4
これで最新版になりました。
テスト用のファイルを用意
SAMのテンプレートファイルを作成します。 今回は「python3.6」としています。
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: SAM Local test Resources: HelloWorld: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: python3.6 Events: GetResource: Type: Api Properties: Path: /resource/{resourceId} Method: put
Lambda実行時に渡すeventファイルを作成します。
{ "body": "Hello World SAM Local" }
Lambda関数のコードを作成します。
import json print('Loading function') def handler(event, context): print("Received event: " + json.dumps(event, indent=2)) return {'statusCode': 200, 'body': "Hello " + json.dumps(event['body']), 'headers': {'Content-Type': 'application/json'}}
構文確認
SAM Localで構文確認をします。 Valid!となればokのようです。
$ sam validate Valid!
動作確認
テスト用のファイルが用意できたら AWS Cloud9上のSAM LocalでLambdaを実行してみましょう。
$ sam local invoke HelloWorld -e event.json 2017/12/20 07:50:24 Successfully parsed template.yaml 2017/12/20 07:50:24 Connected to Docker 1.27 2017/12/20 07:50:24 Fetching lambci/lambda:python3.6 image for python3.6 runtime... python3.6: Pulling from lambci/lambda Digest: sha256: Status: Image is up to date for lambci/lambda:python3.6 2017/12/20 07:50:24 Invoking index.handler (python3.6) 2017/12/20 07:50:24 Mounting /home/ec2-user/environment as /var/task:ro inside runtime container START RequestId: Version: $LATEST Loading function Received event: { "body": "Hello World SAM Local" } END RequestId: REPORT RequestId: Duration: 0 ms Billed Duration: 0 ms Memory Size: 0 MB Max Memory Used: 18 MB {"statusCode": 200, "body": "Hello \"Hello World SAM Local\"", "headers": {"Content-Type": "application/json"}}
作成したプログラム通りに実行されていますね。
トリガー連携のテスト
SAM LocalではLambdaを実行するための トリガーを想定したペイロードが取得できます。
下記はAPI Gatewayをトリガーとした際のeventファイルの出力です。
$ sam local generate-event api --resource /resource { "body": "{ \"test\": \"body\"}", "resource": "/resource", "requestContext": { "resourceId": "123456", "apiId": "1234567890", "resourcePath": "/resource", "httpMethod": "POST", . . .
オプションでパラメータを変更することが可能です。
$ sam local generate-event api --help NAME: sam local generate-event api - Generates a sample Amazon API Gateway event USAGE: sam local generate-event api [command options] [arguments...] OPTIONS: --method value, -m value HTTP method (default: "POST") --body value, -b value HTTP body (default: "{ \\\"test\\\": \\\"body\\\"}") --resource value, -r value API Gateway resource name (default: "/{proxy+}") --path value, -p value HTTP path (default: "/examplepath")
実行はパイプでわたすだけいいので簡単ですね。
$ sam local generate-event api | sam local invoke <logical ID>
API Gatewayのテストをやってみる
SAMのテンプレートをもとに、AWS Cloud9上のSAM Localを使ってAPI Gatewayのテスト実行ができます。 かなり強力です。
下記コマンドで、API サーバを立ててくれます。
$ sam local start-api 2017/12/20 06:43:09 Connected to Docker 1.27 2017/12/20 06:43:09 Fetching lambci/lambda:python3.6 image for python3.6 runtime... python3.6: Pulling from lambci/lambda Digest: sha256: Status: Image is up to date for lambci/lambda:python3.6 Mounting index.handler (python3.6) at http://127.0.0.1:3000/resource/{resourceId} [PUT] You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template.
上記、実行ログより、 http://127.0.0.1:3000/resource/{resourceId}
に対して、リクエストして動作確認をしてみましょう。 新しくターミナルを開き、そこから下記コマンドを実行してみます。
$ curl -H "Accept: application/json" -H "Content-type: application/json" \ -X PUT http://127.0.0.1:3000/resource/hoge \ -d 'sam local' Hello "sam local"
きちんとレスポンスのbody部分がかえってきていることがわかります。
SAM LocalでたてたAPI サーバー側のログは下記のようになってました。
2017/12/20 08:04:05 Invoking index.handler (python3.6) 2017/12/20 08:04:05 Mounting /home/ec2-user/environment as /var/task:ro inside runtime container START RequestId: Version: $LATEST Loading function Received event: { "httpMethod": "PUT", "body": "sam local", "resource": "/resource/hoge", "requestContext": { "resourcePath": "/resource/hoge", "httpMethod": "PUT", "stage": "prod", "identity": { "sourceIp": "127.0.0.1:54768" } }, "queryStringParameters": {}, "headers": { "Accept": "application/json", "Content-Length": "9", "Content-Type": "application/json", "User-Agent": "curl/7.53.1" }, "pathParameters": { "resourceId": "hoge" }, "stageVariables": null, "path": "/resource/hoge" } END RequestId: REPORT RequestId: Duration: 0 ms Billed Duration: 0 ms Memory Size: 0 MB Max Memory Used: 19 MB
Lambdaのコードを修正しても、再起動せずに更新してくれるので大変便利です。
さいごに
いかがだったでしょうか。
AWS Cloud9からSAM Localをためしてみました。 特に問題なく利用できました。
環境構築せずに、SAM Localを利用できるのでとても便利ですね。 AWS Cloud9上からLambda開発がはかどりそうです。
誰かの参考になれば幸いです。